package co.edu.aplicacion.persistencia.impl;

import java.io.FileInputStream;
import java.io.InputStream;
import java.security.MessageDigest;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import co.edu.aplicacion.Cancion;
import co.edu.aplicacion.persistencia.def.IDAOGenerico;
import co.edu.aplicacion.persistencia.fwk.CancionFactory;
import co.edu.aplicacion.persistencia.fwk.ConexionBD;

public class DAOCancion implements IDAOGenerico<Cancion> {

	@Override
	public List<Cancion> consultarTodos() throws Exception {
		List<Cancion> canciones = new ArrayList<Cancion>();
		PreparedStatement ps = null;
		try {
			ConexionBD conexionBD = ConexionBD.getInstance();
			Connection con = conexionBD.getCon();
			String consulta="select " +
					"ccan_id,ccan_genero,ccan_nombre,ccan_ruta,ncan_pista,ccan_album,ccan_md5,CCAN_ARTISTA," +
					"(select CART_NOMBRE FROM ARTISTA_ART WHERE CART_ID=CCAN_ARTISTA) as nombreArtista " +
					"from cancion_can";
			ps = con.prepareStatement(consulta);
			ResultSet rs = ps.executeQuery();
			CancionFactory cancionFactory = new CancionFactory();
			while (rs.next()) {
				canciones.add(cancionFactory.crearCancion(rs));
			}
		} catch (Exception e) {
			throw e;
		} finally {
			if (ps != null) {
				ps.close();
			}
		}
		return canciones;
	}

	@Override
	public List<Cancion> consultarUno() {
		return null;
	}

	public boolean existeCancion(String md5) throws Exception {
		PreparedStatement ps = null;
		try {
			ConexionBD conexionBD = ConexionBD.getInstance();
			Connection con = conexionBD.getCon();
			ps = con.prepareStatement("select * from cancion_can where ccan_md5=?");
			ps.setString(1, md5);
			ResultSet rs=ps.executeQuery();
			return rs.next();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (ps != null) {
				ps.close();
			}
		}
		return false;
	}

	@Override
	public void insertar(Cancion dto) throws Exception {
		PreparedStatement ps = null;
		try {
			ConexionBD conexionBD = ConexionBD.getInstance();
			String md5 = getMD5Checksum(dto.getRuta());
			Connection con = conexionBD.getCon();
			boolean valor=	existeCancion(md5);
			if(valor){
				return;
			}
			ps = con.prepareStatement("insert into cancion_can(ccan_id,ccan_genero,ccan_nombre,ccan_ruta,ncan_pista,ccan_album,ccan_artista,ccan_md5) values(?,?,?,?,?,?,?,?)");
			UUID uuid = UUID.randomUUID();
			String gen = uuid.toString();
			gen = gen.replaceAll("-", "");
			ps.setString(1, gen.substring(0, 32));
			ps.setString(2, dto.getGenero());
			ps.setString(3, dto.getNombre());
			ps.setString(4, dto.getRuta());
			if(dto.getPista()==null){
				ps.setInt(5, 0);
			}else{
				ps.setInt(5, dto.getPista());
			}
			ps.setString(6, dto.getAlbum());
			ps.setString(7, dto.getArtista());
			ps.setString(8, md5);
			ps.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			if (ps != null) {
				ps.close();
			}
		}

	}

	@Override
	public Cancion actualizar(Cancion dto) {
		return null;
	}

	public List<Cancion> consultarCancionArtista(String nombreArtista) throws Exception{
		List<Cancion> canciones = new ArrayList<Cancion>();
		PreparedStatement ps = null;
		try {
			ConexionBD conexionBD = ConexionBD.getInstance();
			Connection con = conexionBD.getCon();
			String consulta="select " +
					"ccan_id,ccan_genero,ccan_nombre,ccan_ruta,ncan_pista,ccan_album,ccan_md5,CCAN_ARTISTA," +
					"CART_NOMBRE as nombreArtista " +
					"from cancion_can,ARTISTA_ART WHERE CART_ID=CCAN_ARTISTA and CART_NOMBRE=?";
			ps = con.prepareStatement(consulta);
			ps.setString(1, nombreArtista);
			ResultSet rs = ps.executeQuery();
			CancionFactory cancionFactory = new CancionFactory();
			while (rs.next()) {
				canciones.add(cancionFactory.crearCancion(rs));
			}
		} catch (Exception e) {
			throw e;
		} finally {
			if (ps != null) {
				ps.close();
			}
		}
		return canciones;
		
	}
	
	
	
	public byte[] createChecksum(String filename) throws Exception {
		InputStream fis = new FileInputStream(filename);

		byte[] buffer = new byte[1024];
		MessageDigest complete = MessageDigest.getInstance("MD5");
		int numRead;

		do {
			numRead = fis.read(buffer);
			if (numRead > 0) {
				complete.update(buffer, 0, numRead);
			}
		} while (numRead != -1);

		fis.close();
		return complete.digest();
	}

	// see this How-to for a faster way to convert
	// a byte array to a HEX string
	public String getMD5Checksum(String filename) throws Exception {
		byte[] b = createChecksum(filename);
		String result = "";

		for (int i = 0; i < b.length; i++) {
			result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
		}
		return result;
	}

}
